﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using XSTDZ.ERP.Application.DataContracts;
using AutoMapper;
using XSTDZ.ERP.Domain.Models;
using XSTDZ.ERP.Core.Repositories;
using XSTDZ.ERP.Core.Generator;

namespace XSTDZ.ERP.Application.Implements
{
    public class StockServiceImpl : ApplicationServiceBase, IStockService
    {
        IRepository<Stock> _stockRepository;
        public StockServiceImpl(IRepositoryContext repositoryContext, IRepository<Stock> stockRepository)
            : base(repositoryContext)
        {
            this._stockRepository = stockRepository;
        }



        public void UpdateStock(StockDto stockDto)
        {
            throw new NotImplementedException();
        }
        public IList<StockDto> AddStockEmpty(IEnumerable<StockDto> stockDtos)
        {
            var existsStocks = new List<Stock>();
            var stocks = Mapper.Map<IEnumerable<StockDto>, IEnumerable<Stock>>(stockDtos).ToList();

            Stock[] dynamicStocks = new Stock[stocks.Count];
            stocks.CopyTo(dynamicStocks);
            foreach (var t in dynamicStocks)
            {
                var tempStock=this._stockRepository.Get(m => m.StorehouseID == t.StorehouseID && m.ProductID == t.ProductID);
                if (tempStock != null)
                {
                    existsStocks.Add(tempStock);
                    stocks.Remove(t);
                    if (stocks == null || stocks.Count() == 0)
                    {
                        break;
                    }
                }
                else
                {
                   t.InitStock(t);
                }
            }
            if (stocks != null && stocks.Count != 0)
            {
                this._stockRepository.Add(stocks);
                this.Context.Commit();
                stocks.Each(t => {
                    t.Storehouse = new Storehouse();
                    t.ProductInfo = new ProductInfo();
                });
                var stockReturns = Mapper.Map<IList<Stock>, IList<StockDto>>(stocks);
                if (existsStocks.Count != 0)
                {
                    return stockReturns.Concat(Mapper.Map<IList<Stock>, IList<StockDto>>(existsStocks)).ToList();
                }
                return stockReturns;
            }
            else if (existsStocks != null && existsStocks.Count() != 0)
            {
                return Mapper.Map<IList<Stock>, IList<StockDto>>(existsStocks);
            }
            return null;
        }
        public void UpdateStock(IEnumerable<StockDto> stockDtos)
        {
            var stocks = Mapper.Map<IEnumerable<StockDto>, IEnumerable<Stock>>(stockDtos);
            UpdateStock(stocks);
            this.Context.Commit();
        }

        public IEnumerable<StockDto> GetStocks()
        {
           var stocks= this._stockRepository.GetAll();
           return Mapper.Map<IEnumerable<Stock>, IEnumerable<StockDto>>(stocks);
        }
        public IEnumerable<StockDto> GetStocksByIds(IEnumerable<Guid> stockIds)
        {
            var stocks = this._stockRepository.GetAll(d => stockIds.Contains(d.Id));
            return Mapper.Map<IEnumerable<Stock>, IEnumerable<StockDto>>(stocks);
        }
        /// <summary>
        /// 更新库存，不允许新增（只能更新数量，不能新增新品种库存)
        /// </summary>
        /// <param name="stockDtos"></param>
        internal void UpdateStockWithNoAdd(IEnumerable<Stock> stockDtos)
        {
            var updateStocks = new List<Stock>();
            stockDtos.Each(s =>
            {
                var existsStock = this._stockRepository.Get(t =>t.Id==s.Id||(t.ProductID==s.ProductID&&t.StorehouseID==s.StorehouseID));
                if (existsStock != null)
                {
                    existsStock.AddStockCount(s);//更新数量
                    updateStocks.Add(existsStock);

                }

            });
            if (updateStocks.Count() != 0)
            {
                this._stockRepository.Update(updateStocks);//更新
            }

        }
        /// <summary>
        /// 更新库存，入库用(若不存在相应仓库，品种的库存，则会新增库存)
        /// </summary>
        /// <param name="stockDtos"></param>
        internal void UpdateStock(IEnumerable<Stock> stockDtos)
        {
            var updateStocks = new List<Stock>();
            stockDtos.Each(s =>
            {
                var existsStock = this._stockRepository.Get(t => t.ProductID != null && t.ProductID == s.ProductID && t.StorehouseID != null && t.StorehouseID == s.StorehouseID);
                if (existsStock != null)
                {
                    existsStock.AddStockCount(s);//更新数量
                    updateStocks.Add(existsStock);

                    s.Id = existsStock.Id;
                }
                
            });
            var insertStocks = stockDtos.Where(s =>s.Id==null||s.Id.Equals(Guid.Empty)).ToList();//获得需要新增 这里不能用这个差集，因为数量不一样
            
            if (insertStocks != null && insertStocks.Count()!=0)
            {
                insertStocks.Each(s => s.InitStock(s));
            }
            #region 取交集,若存在更新和插入的数据，则选择更新操作
            var sameStocks = new List<Stock>(0);
            if(insertStocks!=null&&insertStocks.Count()!=0&&updateStocks!=null&&updateStocks.Count() != 0)
            {
                updateStocks.Each(u=>{
                    insertStocks.Each(i=>{
                        if(u.ProductID==i.ProductID&&u.StorehouseID==i.StorehouseID)
                        {
                            var existStock=sameStocks.Where(s=>s.StorehouseID==u.StorehouseID&&s.ProductID==u.ProductID).FirstOrDefault();
                            if(existStock.Id!=null&&!existStock.Id.Equals(Guid.Empty))
                            {
                                existStock.StockCount+=(i.StockCount+u.StockCount);
                            }
                            else{
                           sameStocks.Add(new Stock{
                             Id=u.Id,
                              StorehouseID=u.StorehouseID,
                               ProductID=u.ProductID,
                                StockCount=i.StockCount+u.StockCount
                           });
                        }
                        }
                    });
                   
                });
            }
	        #endregion
            if (insertStocks.Count() != 0)
            {
                insertStocks = RemoveSame(sameStocks, insertStocks).ToList();//移出和更新有相同性质的项
                var insertList= MerginStock(insertStocks);
                this._stockRepository.Add(insertList);//新增
            }
            if (updateStocks.Count() != 0)
            {
                insertStocks=RemoveSame(sameStocks,updateStocks).Concat(sameStocks).ToList();//移出和更新有相同性质的项
                this._stockRepository.Update(updateStocks);//更新
            }
            
        }
        //移出相同的项
        private IList<Stock> RemoveSame(IList<Stock> sameStocks,IList<Stock> targetStocks)
        {
            if (sameStocks.Count() != 0)
            {
                foreach (var item in targetStocks)
                {
                    foreach (var s in sameStocks)
                    {
                        if (s.ProductID == item.ProductID && s.StorehouseID == item.StorehouseID)
                        {
                            targetStocks.Remove(item);
                            break;
                        }
                    }
                }
            }
            return targetStocks;
        }
        //合并库存
        private IList<Stock> MerginStock(IList<Stock> stocks)
        { 
            var list=new List<Stock>();
            if(stocks!=null&&stocks.Count()!=0)
            {
                stocks.Each(s => {
                    var tag = false;
                    list.Each(t => {
                        if (t.StorehouseID == s.StorehouseID && t.ProductID == s.ProductID)
                        {
                            t.StockCount = t.StockCount + s.StockCount;
                            tag = true;
                        }
                    });
                    if (!tag)
                    {
                        list.Add(s);
                    }
                });
            }
            return list;
        }


       
    }
}
